home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SATAN11.ZIP / SRC / RPCGEN / RPC_PARS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-08  |  9.5 KB  |  433 lines

  1. /* @(#)rpc_parse.c    2.1 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";
  32. #endif
  33.  
  34. /*
  35.  * rpc_parse.c, Parser for the RPC protocol compiler 
  36.  * Copyright (C) 1987 Sun Microsystems, Inc.
  37.  */
  38. #include <stdlib.h>
  39. #include <unistd.h>
  40. #include <stdio.h>
  41. #include "rpc_util.h"
  42. #include "rpc_scan.h"
  43. #include "rpc_parse.h"
  44.  
  45. static isdefined();
  46. static def_struct();
  47. static def_program();
  48. static def_enum();
  49. static def_const();
  50. static def_union();
  51. static def_typedef();
  52. static get_declaration();
  53. static get_type();
  54. static unsigned_dec();
  55.  
  56. /*
  57.  * return the next definition you see
  58.  */
  59. definition *
  60. get_definition()
  61. {
  62.     definition *defp;
  63.     token tok;
  64.  
  65.     defp = ALLOC(definition);
  66.     get_token(&tok);
  67.     switch (tok.kind) {
  68.     case TOK_STRUCT:
  69.         def_struct(defp);
  70.         break;
  71.     case TOK_UNION:
  72.         def_union(defp);
  73.         break;
  74.     case TOK_TYPEDEF:
  75.         def_typedef(defp);
  76.         break;
  77.     case TOK_ENUM:
  78.         def_enum(defp);
  79.         break;
  80.     case TOK_PROGRAM:
  81.         def_program(defp);
  82.         break;
  83.     case TOK_CONST:
  84.         def_const(defp);
  85.         break;
  86.     case TOK_EOF:
  87.         return (NULL);
  88.         break;
  89.     default:
  90.         error("definition keyword expected");
  91.     }
  92.     scan(TOK_SEMICOLON, &tok);
  93.     isdefined(defp);
  94.     return (defp);
  95. }
  96.  
  97. static
  98. isdefined(defp)
  99.     definition *defp;
  100. {
  101.     STOREVAL(&defined, defp);
  102. }
  103.  
  104.  
  105. static
  106. def_struct(defp)
  107.     definition *defp;
  108. {
  109.     token tok;
  110.     declaration dec;
  111.     decl_list *decls;
  112.     decl_list **tailp;
  113.  
  114.     defp->def_kind = DEF_STRUCT;
  115.  
  116.     scan(TOK_IDENT, &tok);
  117.     defp->def_name = tok.str;
  118.     scan(TOK_LBRACE, &tok);
  119.     tailp = &defp->def.st.decls;
  120.     do {
  121.         get_declaration(&dec, DEF_STRUCT);
  122.         decls = ALLOC(decl_list);
  123.         decls->decl = dec;
  124.         *tailp = decls;
  125.         tailp = &decls->next;
  126.         scan(TOK_SEMICOLON, &tok);
  127.         peek(&tok);
  128.     } while (tok.kind != TOK_RBRACE);
  129.     get_token(&tok);
  130.     *tailp = NULL;
  131. }
  132.  
  133. static
  134. def_program(defp)
  135.     definition *defp;
  136. {
  137.     token tok;
  138.     version_list *vlist;
  139.     version_list **vtailp;
  140.     proc_list *plist;
  141.     proc_list **ptailp;
  142.  
  143.     defp->def_kind = DEF_PROGRAM;
  144.     scan(TOK_IDENT, &tok);
  145.     defp->def_name = tok.str;
  146.     scan(TOK_LBRACE, &tok);
  147.     vtailp = &defp->def.pr.versions;
  148.     scan(TOK_VERSION, &tok);
  149.     do {
  150.         scan(TOK_IDENT, &tok);
  151.         vlist = ALLOC(version_list);
  152.         vlist->vers_name = tok.str;
  153.         scan(TOK_LBRACE, &tok);
  154.         ptailp = &vlist->procs;
  155.         do {
  156.             plist = ALLOC(proc_list);
  157.             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
  158.             if (streq(plist->res_type, "opaque")) {
  159.                 error("illegal result type");
  160.             }
  161.             scan(TOK_IDENT, &tok);
  162.             plist->proc_name = tok.str;
  163.             scan(TOK_LPAREN, &tok);
  164.             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
  165.             if (streq(plist->arg_type, "opaque")) {
  166.                 error("illegal argument type");
  167.             }
  168.             scan(TOK_RPAREN, &tok);
  169.             scan(TOK_EQUAL, &tok);
  170.             scan_num(&tok);
  171.             scan(TOK_SEMICOLON, &tok);
  172.             plist->proc_num = tok.str;
  173.             *ptailp = plist;
  174.             ptailp = &plist->next;
  175.             peek(&tok);
  176.         } while (tok.kind != TOK_RBRACE);
  177.         *vtailp = vlist;
  178.         vtailp = &vlist->next;
  179.         scan(TOK_RBRACE, &tok);
  180.         scan(TOK_EQUAL, &tok);
  181.         scan_num(&tok);
  182.         vlist->vers_num = tok.str;
  183.         scan(TOK_SEMICOLON, &tok);
  184.         scan2(TOK_VERSION, TOK_RBRACE, &tok);
  185.     } while (tok.kind == TOK_VERSION);
  186.     scan(TOK_EQUAL, &tok);
  187.     scan_num(&tok);
  188.     defp->def.pr.prog_num = tok.str;
  189.     *vtailp = NULL;
  190. }
  191.  
  192. static
  193. def_enum(defp)
  194.     definition *defp;
  195. {
  196.     token tok;
  197.     enumval_list *elist;
  198.     enumval_list **tailp;
  199.  
  200.     defp->def_kind = DEF_ENUM;
  201.     scan(TOK_IDENT, &tok);
  202.     defp->def_name = tok.str;
  203.     scan(TOK_LBRACE, &tok);
  204.     tailp = &defp->def.en.vals;
  205.     do {
  206.         scan(TOK_IDENT, &tok);
  207.         elist = ALLOC(enumval_list);
  208.         elist->name = tok.str;
  209.         elist->assignment = NULL;
  210.         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
  211.         if (tok.kind == TOK_EQUAL) {
  212.             scan_num(&tok);
  213.             elist->assignment = tok.str;
  214.             scan2(TOK_COMMA, TOK_RBRACE, &tok);
  215.         }
  216.         *tailp = elist;
  217.         tailp = &elist->next;
  218.     } while (tok.kind != TOK_RBRACE);
  219.     *tailp = NULL;
  220. }
  221.  
  222. static
  223. def_const(defp)
  224.     definition *defp;
  225. {
  226.     token tok;
  227.  
  228.     defp->def_kind = DEF_CONST;
  229.     scan(TOK_IDENT, &tok);
  230.     defp->def_name = tok.str;
  231.     scan(TOK_EQUAL, &tok);
  232.     scan2(TOK_IDENT, TOK_STRCONST, &tok);
  233.     defp->def.co = tok.str;
  234. }
  235.  
  236. static
  237. def_union(defp)
  238.     definition *defp;
  239. {
  240.     token tok;
  241.     declaration dec;
  242.     case_list *cases;
  243.     case_list **tailp;
  244.  
  245.     defp->def_kind = DEF_UNION;
  246.     scan(TOK_IDENT, &tok);
  247.     defp->def_name = tok.str;
  248.     scan(TOK_SWITCH, &tok);
  249.     scan(TOK_LPAREN, &tok);
  250.     get_declaration(&dec, DEF_UNION);
  251.     defp->def.un.enum_decl = dec;
  252.     tailp = &defp->def.un.cases;
  253.     scan(TOK_RPAREN, &tok);
  254.     scan(TOK_LBRACE, &tok);
  255.     scan(TOK_CASE, &tok);
  256.     while (tok.kind == TOK_CASE) {
  257.         scan(TOK_IDENT, &tok);
  258.         cases = ALLOC(case_list);
  259.         cases->case_name = tok.str;
  260.         scan(TOK_COLON, &tok);
  261.         get_declaration(&dec, DEF_UNION);
  262.         cases->case_decl = dec;
  263.         *tailp = cases;
  264.         tailp = &cases->next;
  265.         scan(TOK_SEMICOLON, &tok);
  266.         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  267.     }
  268.     *tailp = NULL;
  269.     if (tok.kind == TOK_DEFAULT) {
  270.         scan(TOK_COLON, &tok);
  271.         get_declaration(&dec, DEF_UNION);
  272.         defp->def.un.default_decl = ALLOC(declaration);
  273.         *defp->def.un.default_decl = dec;
  274.         scan(TOK_SEMICOLON, &tok);
  275.         scan(TOK_RBRACE, &tok);
  276.     } else {
  277.         defp->def.un.default_decl = NULL;
  278.     }
  279. }
  280.  
  281.  
  282. static
  283. def_typedef(defp)
  284.     definition *defp;
  285. {
  286.     declaration dec;
  287.  
  288.     defp->def_kind = DEF_TYPEDEF;
  289.     get_declaration(&dec, DEF_TYPEDEF);
  290.     defp->def_name = dec.name;
  291.     defp->def.ty.old_prefix = dec.prefix;
  292.     defp->def.ty.old_type = dec.type;
  293.     defp->def.ty.rel = dec.rel;
  294.     defp->def.ty.array_max = dec.array_max;
  295. }
  296.  
  297.  
  298. static
  299. get_declaration(dec, dkind)
  300.     declaration *dec;
  301.     defkind dkind;
  302. {
  303.     token tok;
  304.  
  305.     get_type(&dec->prefix, &dec->type, dkind);
  306.     dec->rel = REL_ALIAS;
  307.     if (streq(dec->type, "void")) {
  308.         return;
  309.     }
  310.     scan2(TOK_STAR, TOK_IDENT, &tok);
  311.     if (tok.kind == TOK_STAR) {
  312.         dec->rel = REL_POINTER;
  313.         scan(TOK_IDENT, &tok);
  314.     }
  315.     dec->name = tok.str;
  316.     if (peekscan(TOK_LBRACKET, &tok)) {
  317.         if (dec->rel == REL_POINTER) {
  318.             error("no array-of-pointer declarations -- use typedef");
  319.         }
  320.         dec->rel = REL_VECTOR;
  321.         scan_num(&tok);
  322.         dec->array_max = tok.str;
  323.         scan(TOK_RBRACKET, &tok);
  324.     } else if (peekscan(TOK_LANGLE, &tok)) {
  325.         if (dec->rel == REL_POINTER) {
  326.             error("no array-of-pointer declarations -- use typedef");
  327.         }
  328.         dec->rel = REL_ARRAY;
  329.         if (peekscan(TOK_RANGLE, &tok)) {
  330.             dec->array_max = "~0";    /* unspecified size, use max */
  331.         } else {
  332.             scan_num(&tok);
  333.             dec->array_max = tok.str;
  334.             scan(TOK_RANGLE, &tok);
  335.         }
  336.     }
  337.     if (streq(dec->type, "opaque")) {
  338.         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
  339.             error("array declaration expected");
  340.         }
  341.     } else if (streq(dec->type, "string")) {
  342.         if (dec->rel != REL_ARRAY) {
  343.             error("variable-length array declaration expected");
  344.         }
  345.     }
  346. }
  347.  
  348.  
  349. static
  350. get_type(prefixp, typep, dkind)
  351.     char **prefixp;
  352.     char **typep;
  353.     defkind dkind;
  354. {
  355.     token tok;
  356.  
  357.     *prefixp = NULL;
  358.     get_token(&tok);
  359.     switch (tok.kind) {
  360.     case TOK_IDENT:
  361.         *typep = tok.str;
  362.         break;
  363.     case TOK_STRUCT:
  364.     case TOK_ENUM:
  365.     case TOK_UNION:
  366.         *prefixp = tok.str;
  367.         scan(TOK_IDENT, &tok);
  368.         *typep = tok.str;
  369.         break;
  370.     case TOK_UNSIGNED:
  371.         unsigned_dec(typep);
  372.         break;
  373.     case TOK_SHORT:
  374.         *typep = "short";
  375.         (void) peekscan(TOK_INT, &tok);
  376.         break;
  377.     case TOK_LONG:
  378.         *typep = "long";
  379.         (void) peekscan(TOK_INT, &tok);
  380.         break;
  381.     case TOK_VOID:
  382.         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
  383.             error("voids allowed only inside union and program definitions");
  384.         }
  385.         *typep = tok.str;
  386.         break;
  387.     case TOK_STRING:
  388.     case TOK_OPAQUE:
  389.     case TOK_CHAR:
  390.     case TOK_INT:
  391.     case TOK_FLOAT:
  392.     case TOK_DOUBLE:
  393.     case TOK_BOOL:
  394.         *typep = tok.str;
  395.         break;
  396.     default:
  397.         error("expected type specifier");
  398.     }
  399. }
  400.  
  401.  
  402. static
  403. unsigned_dec(typep)
  404.     char **typep;
  405. {
  406.     token tok;
  407.  
  408.     peek(&tok);
  409.     switch (tok.kind) {
  410.     case TOK_CHAR:
  411.         get_token(&tok);
  412.         *typep = "u_char";
  413.         break;
  414.     case TOK_SHORT:
  415.         get_token(&tok);
  416.         *typep = "u_short";
  417.         (void) peekscan(TOK_INT, &tok);
  418.         break;
  419.     case TOK_LONG:
  420.         get_token(&tok);
  421.         *typep = "u_long";
  422.         (void) peekscan(TOK_INT, &tok);
  423.         break;
  424.     case TOK_INT:
  425.         get_token(&tok);
  426.         *typep = "u_int";
  427.         break;
  428.     default:
  429.         *typep = "u_int";
  430.         break;
  431.     }
  432. }
  433.